package com.hengli.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.hengli.constant.MessageConstant;
import com.hengli.constant.StatusConstant;
import com.hengli.dto.WineDTO;
import com.hengli.dto.WinePageQueryDTO;
import com.hengli.entity.Wine;
import com.hengli.entity.WineSpecification;
import com.hengli.entity.Winepackage;
import com.hengli.exception.DeletionNotAllowedException;
import com.hengli.mapper.WineMapper;
import com.hengli.mapper.WineSpecificationMapper;
import com.hengli.mapper.WinepackageMapper;
import com.hengli.mapper.WinepackageWineMapper;
import com.hengli.result.PageResult;
import com.hengli.service.WineService;
import com.hengli.vo.WineVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * @author ljx
 * @date 2024/3/24 15:28
 */
@Service
@Slf4j
public class WineServiceImpl implements WineService {

    @Autowired
    private WineMapper wineMapper;

    @Autowired
    private WineSpecificationMapper winespecificationMapper;

    @Autowired
    private WinepackageWineMapper winepackageWineMapper;

    @Autowired
    private WinepackageMapper winepackageMapper;
    /**
     * 新增新增酒品及规格
     *
     * @param wineDTO
     */
    @Transactional
    public void saveWithSpecification(WineDTO wineDTO) {

        Wine wine = new Wine();
        BeanUtils.copyProperties(wineDTO, wine);

        //向酒品表中插入一条数据
        wineMapper.insert(wine);
        //获取上面INSERT语句生成的主键值
        Long wineId = wine.getId();

        List<WineSpecification> specifications = wineDTO.getSpecifications();
        if (specifications != null && specifications.size() > 0) {
            specifications.forEach(specification -> {
                specification.setWineId(wineId);
            });

            //向规格表插入N条数据,批量插入
            winespecificationMapper.insertBatch(specifications);
        }
    }

    /**
     * 酒品分页查询
     *
     * @param winePageQueryDTO
     * @return
     */
    public PageResult pageQuery(WinePageQueryDTO winePageQueryDTO) {
        PageHelper.startPage(winePageQueryDTO.getPage(), winePageQueryDTO.getPageSize());
        Page<WineVO> page = wineMapper.pageQuery(winePageQueryDTO);//后绪步骤实现
        return new PageResult(page.getTotal(), page.getResult());
    }

    /**
     * 酒品批量删除
     *
     * @param ids
     */
    @Transactional//事务
    public void deleteBatch(List<Long> ids) {
//判断当前酒品是否能够删除---是否存在起售中的酒品？？
        for (Long id : ids) {
            Wine wine = wineMapper.getById(id);//后绪步骤实现
            log.info("当前酒品状态为：{}", wine.getStatus());
            if (wine.getStatus() == StatusConstant.ENABLE) {
                //当前酒品处于起售中，不能删除
                throw new DeletionNotAllowedException(MessageConstant.WINE_ON_SALE);
            }
        }

        //判断当前酒品是否能够删除---是否被套餐关联了？？
        List<Long> WinepackageIds = winepackageWineMapper.getWinepackageIdsByWineIds(ids);
        if (WinepackageIds != null && WinepackageIds.size() > 0) {
            //当前酒品被套餐关联了，不能删除
            throw new DeletionNotAllowedException(MessageConstant.WINE_BE_RELATED_BY_WINEPACKAGE);
        }

        //删除酒品表中的酒品数据
        for (Long id : ids) {
            wineMapper.deleteById(id);//后绪步骤实现
            //删除酒品关联的规格数据
            winespecificationMapper.deleteByWineId(id);//后绪步骤实现
        }
    }

    /**
     * 根据id查询酒品和对应的规格数据
     *
     * @param id
     * @return
     */
    public WineVO getByIdWithSpecification(Long id) {
        //根据id查询酒品数据
        Wine wine = wineMapper.getById(id);

        //根据酒品id查询规格数据
        List<WineSpecification> wineSpecifications = winespecificationMapper.getByWineId(id);//后绪步骤实现

        //将查询到的数据封装到VO
        WineVO wineVO = new WineVO();
        BeanUtils.copyProperties(wine, wineVO);
        wineVO.setSpecifications(wineSpecifications);

        return wineVO;
    }

    /**
     * 根据id修改酒品基本信息和对应的规格信息
     *
     * @param wineDTO
     */
    public void updateWithSpecification(WineDTO wineDTO) {
        Wine wine = new Wine();
        BeanUtils.copyProperties(wineDTO, wine);

        //修改酒品表基本信息
        wineMapper.update(wine);

        //删除原有的规格数据
        winespecificationMapper.deleteByWineId(wineDTO.getId());

        //重新插入规格数据
        List<WineSpecification> specifications = wineDTO.getSpecifications();
        if (specifications != null && specifications.size() > 0) {
            specifications.forEach(WineSpecification -> {
                WineSpecification.setWineId(wineDTO.getId());
            });
            //向规格表插入n条数据
            winespecificationMapper.insertBatch(specifications);
        }
    }

    /**
     * 酒品起售停售
     *
     * @param status
     * @param id
     */
    @Transactional
    public void startOrStop(Integer status, Long id) {
        Wine wine = Wine.builder()
                .id(id)
                .status(status)
                .build();
        wineMapper.update(wine);

        if (status == StatusConstant.DISABLE) {
            // 如果是停售操作，还需要判断当前酒品的套餐是否起售停售
            List<Long> wineIds = new ArrayList<>();
            wineIds.add(id);
            List<Long> winepackageIds = winepackageWineMapper.getWinepackageIdsByWineIds(wineIds);
            if (winepackageIds != null && winepackageIds.size() > 0) {
                for (Long winepackageId : winepackageIds) {
                    Winepackage winepackage = Winepackage.builder()
                            .id(winepackageId)
                            .status(StatusConstant.DISABLE)
                            .build();
                    winepackageMapper.update(winepackage);
                }
            }
        }
    }

    /**
     * 根据id查询酒品数据
     *
     * @param id
     * @return
     */
    @Override
    public List<Wine> list(Integer id) {
        return wineMapper.list(id);
    }

    /**
     * 条件查询酒品和规格
     * @param wine
     * @return
     */
    public List<WineVO> listWithSpecification(Wine wine) {
        List<Wine> wineList = wineMapper.list(Math.toIntExact(wine.getCategoryId()));

        List<WineVO> wineVOList = new ArrayList<>();

        for (Wine d : wineList) {
            WineVO wineVO = new WineVO();
            BeanUtils.copyProperties(d,wineVO);

            //根据菜品id查询对应的口味
            List<WineSpecification> specifications = winespecificationMapper.getByWineId(d.getId());

            wineVO.setSpecifications(specifications);
            wineVOList.add(wineVO);
        }

        return wineVOList;
    }
}
